<?php

namespace addons\booking\model;

use think\Model;
use addons\booking\model\House;
use addons\booking\model\Coupon;
use addons\booking\model\UserCoupon;
use addons\booking\model\CouponCondition;
use addons\booking\library\IntCode;
use think\Db;

class Store extends Model
{

    // 表名
    protected $name = 'booking_store';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = false;

    // 追加属性
    protected $append = [];

    public function getImagesAttr($value, $data)
    {
        $value = $value ? $value : ($data['images'] ?? '');
        if (!$value) {
            return [];
        }
        $value = array_filter(explode(',', $value));
        foreach ($value as &$item) {
            $item = cdnurl($item, true);
        }
        return $value;
    }

    public function getImageAttr($value, $data)
    {
        $value = $value ? $value : ($data['images'] ?? '');
        if (!$value) {
            return '';
        }
        $value = array_filter(explode(',', $value));

        return isset($value[0]) ? cdnurl($value[0], true) : '';
    }

    /**
     * 门店列表
     *
     * @param array $param
     * @return \think\Paginator
     */
    public static function tableList($param,$userid='')
    {
        $pageNum = 15;
        if (isset($param['num']) && !empty($param['num'])) {
            $pageNum = $param['num'];
        }
        $field = ['id', 'name', 'intro', 'images', 'address', 'phone', 'latitude', 'longitude', 'createtime'];
        $store_order = 'weigh desc,id desc';
        //根据距离取值
        $PI = M_PI;
        $meter="";
        $distanceSql="";
        if (isset($param['latitude']) && isset($param['longitude']) && !empty($param['latitude']) && !empty($param['longitude'])) {
            $field[] = "(2 * 6378.137 * ASIN(SQRT(POW(SIN($PI*({$param['latitude']}-latitude)/360),2)+COS($PI*{$param['latitude']}/180)* COS(latitude * $PI/180)*POW(SIN($PI*({$param['longitude']}-longitude)/360),2)))) as distance";
            
             $distanceSql = "(2 * 6378.137 * ASIN(SQRT(POW(SIN($PI*({$param['latitude']}-latitude)/360),2)+COS($PI*{$param['latitude']}/180)* COS(latitude * $PI/180)*POW(SIN($PI*({$param['longitude']}-longitude)/360),2))))";
             //组合距离sql
            // $distanceSql = "(6378.138 * 2 * asin(sqrt(pow(sin((latitude * pi() / 180 - ".$param['latitude']." * pi() / 180) / 2),2) + cos(latitude * pi() / 180) * cos(".$param['latitude']." * pi() / 180) * pow(sin((longitude * pi() / 180 - ".$param['longitude']." * pi() / 180) / 2),2))) * 1000)";
          
            if(isset($param['meter'])){
                $meter=isset($param['meter']) ?  $param['meter'] :20;
                // $where["distance"]=["<",$meter];
             
            }
        }
        $where['status'] = 'normal';
        if(isset($param['category_id'])&&$param['category_id']){
            $where['category_id'] = $param['category_id'];
        }
        if(isset($param['city'])&&$param['city'] && $param['city']!="全国"){
            $where['address'] = ['like','%'.$param['city'].'%'];
        }
         if (isset($param['keyword']) && !empty($param['keyword'])) {
            $where['name'] = ['like', '%' . $param['keyword'] . '%'];
        }
         //按日期筛选房间【排除被预订的】
        if (isset($param['calendar']) && !empty($param['calendar'])) {
            $calendar = explode('/', $param['calendar']);
            $time1 = strtotime($calendar[0]);
            $time2 = $time1 + 3600 * 24;
            if (count($calendar) == 2) { //时间范围
                $time2 = strtotime($calendar[1]);
            }
            $data = OrderCalendar::field('house_id')->where('status', 'normal')->where('reserve_time', '>=', $time1)->where('reserve_time', '<', $time2)->group('house_id')->select();
            $house_ids = [];
            foreach ($data as $item) {
                $house_ids[$item['house_id']] = $item['house_id'];
            }
            // var_dump($house_ids);die;
            $store_ids = House::where('id', 'in', $house_ids)->column("store_id");
            if($store_ids){
                $where['id'] = ['not in',$store_ids];
            }
            
        }
        if(isset($param['orderby'])){
             $time = strtotime(date('Y-m-d'));
            $house_field = 't.name as type_name,h.store_id,';
            $house_field .= 'h.id,h.market_price,h.tag_config_ids,h.name,h.views,h.area,h.livenums,h.status,h.images,h.createtime,';
            $house_field .= 'GROUP_CONCAT(c.name ORDER BY FIND_IN_SET(c.id, h.tag_config_ids)) tag_names,';
            $house_field .= "if(d.price>0,d.price,h.price) as house_price";
             $house_where = self::getTableWhere($param);
            //排序
            $order = self::getTableOrderBy($param);
            // var_dump($house_field);die;
            $house_query = House::field($house_field)->where($house_where)
                ->alias('h')
                ->join('booking_config c', 'FIND_IN_SET(c.id,h.tag_config_ids)', 'LEFT')
                ->join('booking_config t', 'h.type_config_id=t.id', 'LEFT')
                ->join('booking_calendar d', 'd.house_id=h.id AND d.day_time=' . $time, 'LEFT')
                ->group('h.id')
                ->order($order);
            $house_list = $house_query->select();
            if($house_list){
                $storeids = array_column($house_list,'store_id');
                // var_dump($storeids);die;
                $where['id'] = ['in',$storeids];
                $store_order = new \think\db\Expression('field(id,' . implode(',', $storeids) . ')');
            }
        }
       
       if($distanceSql && $meter){
           $list = self::field($field)
            ->where(function ($query) use ($param) {
            })
            ->where($where)
            ->where(Db::raw($distanceSql . "<=" . ($meter)))  //获取多少范围之内
            ->order($store_order)
            ->paginate($pageNum);
       }else{
           $list = self::field($field)
            ->where(function ($query) use ($param) {
            })
            ->where($where)
            ->order($store_order)
            ->paginate($pageNum);
       }
       
        foreach ($list as $ik=>&$item) {
            $item->append(['image']);
            $item->hidden(['images']);
            $price_between=isset($param["price"]) ? explode("-",$param["price"]) :"";
            if($price_between){
                $hw["h.price"]=["between",[$price_between[0],$price_between[1]]];
            }
            $hw["h.status"]="up";
            $hw["h.store_id"]=$item['id'];
            //房间
            $houseInfo = House::alias("h")
                        ->join('booking_config c', 'FIND_IN_SET(c.id,h.tag_config_ids)', 'LEFT')
                        ->where($hw)
                        ->field("h.id,h.market_price,h.price,GROUP_CONCAT(c.name ORDER BY FIND_IN_SET(c.id, h.tag_config_ids)) tag_names")
                        ->order("h.weigh desc,h.price desc")
                        ->find();
           
            // var_dump($item['id']);die;
            $newList = [];
            $item['tag_names'] = [];
            $item['market_price'] = 0;
            $item['price'] = 0;
            if($houseInfo && isset($houseInfo["id"]) && $houseInfo["id"]>0){
                $item['tag_names'] = $houseInfo['tag_names'];
                $item['market_price'] = $houseInfo['market_price'];
                $item['price'] = $houseInfo['price'];
               //优惠券
                $conditions = CouponCondition::getHouseCondition($houseInfo['id'], $item['id']);
                
                $sql = "condition_ids IS NULL OR condition_ids=''";
                foreach ($conditions as $key => $val) {
                    $val['id'] = (int)$val['id'];
                    $sql .= " OR FIND_IN_SET('{$val['id']}',condition_ids)";
                }
                $coupon_list = Coupon::field('id,name,result,result_data,alone_num,receive_times,mode,createtime,received_num,give_num')->where($sql)->select();
                // var_dump($coupon_list);die;
                //已经登录，渲染已领的优惠券
                $coupon_ids = [];
                // var_dump($userid);die;
                if ($userid) {
                    $coupon_ids = UserCoupon::where('user_id', $userid)->column('coupon_id');
                }
                $newList = [];
                foreach ($coupon_list as $v) {
                    Coupon::render($v, $coupon_ids);
                    $v->id = IntCode::encode($v->id);
                    $newList[] = $v;
                }
                unset($coupon_list);   
            }else{
               unset($list[$ik]);
            }
           
    
            $item['coupon'] = $newList?$newList[0]:[];
        }
         if (isset($param['calendar']) && !empty($param['calendar'])) {
             $calendar = explode('/', $param['calendar']);
            $time1 = strtotime($calendar[0]);
            $time2 = $time1 + 3600 * 24;
            if (count($calendar) == 2) { //时间范围
                $time2 = strtotime($calendar[1]);
            }
            // array_merge($list,['start_time'=>date('m.d',$time1),'end_time'=>date("m.d",$time2)]);
            // $list['start_time'] = date('m.d',$time1);
            // $list['end_time'] = date("m.d",$time2);
            $data['start_time'] = date('m.d',$time1);
            $data['end_time'] = date("m.d",$time2);
        }
        $data['list'] = $list;
        return $data;
    }
 /**
     * 条件处理
     *
     * @param array $param
     * @return void
     */
    private static function getTableWhere($param)
    {
        return function ($query) use ($param) {
            $query->where('h.status', 'up');
            //门店id
            if (isset($param['store_id']) && !empty($param['store_id'])) {
                $query->where('h.store_id', $param['store_id']);
            }
            //门店ids
            if (isset($param['store_ids']) && !empty($param['store_ids'])) {
                $query->where('h.store_id', 'in', $param['store_ids']);
            }
            //门店ids
            if (isset($param['keyword']) && !empty($param['keyword'])) {
                $query->where('h.name|h.intro', 'like', '%' . $param['keyword'] . '%');
            }
            //按日期筛选房间【排除被预订的】
            if (isset($param['calendar']) && !empty($param['calendar'])) {
                $calendar = explode('/', $param['calendar']);
                $time1 = strtotime($calendar[0]);
                $time2 = $time1 + 3600 * 24;
                if (count($calendar) == 2) { //时间范围
                    $time2 = strtotime($calendar[1]);
                }
                $data = OrderCalendar::field('house_id')->where('status', 'normal')->where('reserve_time', '>=', $time1)->where('reserve_time', '<', $time2)->group('house_id')->select();
                $house_ids = [];
                foreach ($data as $item) {
                    $house_ids[$item['house_id']] = $item['house_id'];
                }
                $query->where('h.id', 'not in', $house_ids);
            }
            //房间ids
            if (isset($param['house_ids']) && !empty($param['house_ids'])) {
                $query->where('h.id', 'in', $param['house_ids']);
            }
            //房型
            if (isset($param['house']) && !empty($param['house'])) {
                if (isset($param['multiple']) && $param['multiple']) { //多选
                    $query->where('h.type_config_id', 'in', $param['house']);
                } else {
                    $query->where('h.type_config_id', $param['house']);
                }
            }
            //标签
            if (isset($param['tag']) && !empty($param['tag'])) {
                if (isset($param['multiple']) && $param['multiple']) { //多选
                    $tagArr = explode(',', $param['tag']);
                    $sql = '1=1';
                    foreach ($tagArr as $id) {
                        $id = (int)$id;
                        $sql .= " AND FIND_IN_SET($id,h.tag_config_ids)";
                    }
                    $query->where($sql);
                } else {
                    $query->where("FIND_IN_SET(" . intval($param['tag']) . ",h.tag_config_ids)");
                }
            }
            //楼层
            if (isset($param['floor']) && !empty($param['floor'])) {
                if (isset($param['multiple']) && $param['multiple']) { //多选
                    $query->where('h.floor_config_id', 'in', $param['floor']);
                } else {
                    $query->where('h.floor_config_id', $param['floor']);
                }
            }
            //配套设施
            if (isset($param['facility']) && !empty($param['facility'])) {
                if (isset($param['multiple']) && $param['multiple']) { //多选
                    $facilityArr = explode(',', $param['facility']);
                    $sql = '1=1';
                    foreach ($facilityArr as $id) {
                        $id = (int)$id;
                        $sql .= " AND FIND_IN_SET($id,h.facility_config_ids)";
                    }
                    $query->where($sql);
                } else {
                    $query->where("FIND_IN_SET(" . intval($param['facility']) . ",h.facility_config_ids)");
                }
            }
            //价格区间
            if (isset($param['price']) && !empty($param['price'])) {
                $array = explode('-', $param['price']);
                if (count($array) == 2) {
                    $query->where('h.price|d.price', 'between', $array);
                }
            }
            //可住人数区间
            if (isset($param['nums']) && !empty($param['nums'])) {
                $array = explode('-', $param['nums']);
                if (count($array) == 2) {
                    $query->where('h.livenums', 'between', $array);
                }
            }
        };
    }
      /**
     * 排序出来了
     *
     * @param array $param
     * @return void
     */
    private static function getTableOrderBy($param)
    {
        $order = 'h.weigh desc';
        if (isset($param['orderby'])) {

            switch ($param['orderby']) {
                case 'comment':
                    //统计评论得分最高的，房间，排序
                    $list = Comment::field('sum(grade) as grades,source_id')
                        ->where('type', 0)
                        ->where('status', 'normal')
                        ->group('source_id')
                        ->order('grades desc')
                        ->select();

                    $source_ids = join(',', array_column($list, 'source_id'));
                    $order = new \think\db\Expression("field(h.id,$source_ids)");
                    break;
                case 'low_price':
                    $order = 'house_price asc';
                    break;
                case 'high_price':
                    $order = 'house_price desc';
                    break;
                case 'views':
                    $order = 'h.views desc';
                    break;
                case 'distance':
                    //取门店的按坐标排序，房间按门店拍讯
                    if (isset($param['latitude']) && !empty($param['latitude']) && isset($param['longitude']) && !empty($param['longitude'])) {
                        $latitude = $param['latitude'];
                        $longitude = $param['longitude'];
                        $PI = M_PI;
                        $fields = "id,latitude,longitude,(2 * 6378.137 * ASIN(SQRT(POW(SIN($PI*({$latitude}-latitude)/360),2)+COS($PI*{$latitude}/180)* COS(latitude * $PI/180)*POW(SIN($PI*({$longitude}-longitude)/360),2)))) as distance";
                        $store = \addons\booking\model\Store::field($fields)->order('distance asc')->select();
                        $store_ids = join(',', array_column($store, 'id'));
                        $order = new \think\db\Expression("field(h.store_id,$store_ids)");
                    }
                    break;
            }
        }
        return $order;
    }

    /**
     * 门店列表
     *
     * @param array $param
     * @return \think\Paginator
     */
    public static function indexTableList($param,$userid='')
    {
        // $pageNum = 15;
        // if (isset($param['num']) && !empty($param['num'])) {
        //     $pageNum = $param['num'];
        // }
        $field = ['id', 'name', 'intro', 'images', 'address', 'phone', 'latitude', 'longitude', 'createtime'];
        //根据距离取值
        $PI = M_PI;
        if (isset($param['latitude']) && isset($param['longitude']) && !empty($param['latitude']) && !empty($param['longitude'])) {
            $field[] = "(2 * 6378.137 * ASIN(SQRT(POW(SIN($PI*({$param['latitude']}-latitude)/360),2)+COS($PI*{$param['latitude']}/180)* COS(latitude * $PI/180)*POW(SIN($PI*({$param['longitude']}-longitude)/360),2)))) as distance";
        }
        $list = self::field($field)
            ->where(function ($query) use ($param) {
            })
            ->where(['status'=>'normal','is_recommend'=>1])
            ->order('weigh desc,id desc')
            ->select();

        foreach ($list as &$item) {
            $item->append(['image']);
            $item->hidden(['images']);
            //房间
            $houseInfo = House::alias("h")
                        ->join('booking_config c', 'FIND_IN_SET(c.id,h.tag_config_ids)', 'LEFT')
                        ->where(['h.status'=>'up','h.store_id'=>$item['id']])
                        ->field("h.id,h.market_price,h.price,GROUP_CONCAT(c.name ORDER BY FIND_IN_SET(c.id, h.tag_config_ids)) tag_names")
                        ->order("h.weigh desc,h.price desc")
                        ->find();
            // var_dump($item['id']);die;
            $newList = [];
            $item['tag_names'] = [];
            $item['market_price'] = 0;
            $item['price'] = 0;
            if($houseInfo){
                $item['tag_names'] = $houseInfo['tag_names'];
                $item['market_price'] = $houseInfo['market_price'];
                $item['price'] = $houseInfo['price'];
               //优惠券
                $conditions = CouponCondition::getHouseCondition($houseInfo['id'], $item['id']);
                
                $sql = "condition_ids IS NULL OR condition_ids=''";
                foreach ($conditions as $key => $val) {
                    $val['id'] = (int)$val['id'];
                    $sql .= " OR FIND_IN_SET('{$val['id']}',condition_ids)";
                }
                $coupon_list = Coupon::field('id,name,result,result_data,alone_num,receive_times,mode,createtime,received_num,give_num')->where($sql)->select();
                // var_dump($coupon_list);die;
                //已经登录，渲染已领的优惠券
                $coupon_ids = [];
                // var_dump($userid);die;
                if ($userid) {
                    $coupon_ids = UserCoupon::where('user_id', $userid)->column('coupon_id');
                }
                $newList = [];
                foreach ($coupon_list as $v) {
                    Coupon::render($v, $coupon_ids);
                    $v->id = IntCode::encode($v->id);
                    $newList[] = $v;
                }
                unset($coupon_list);   
            }
            $item['coupon'] = $newList?$newList[0]:[];
        }
        return $list;
    }
    public static function getDetail($id,$param=null)
    {
        $field = ['id', 'name', 'intro', 'images','avatar', 'address', 'phone', 'latitude', 'longitude', 'createtime'];
        if (isset($param['latitude']) && isset($param['longitude']) && !empty($param['latitude']) && !empty($param['longitude'])) {
             //根据距离取值
            $PI = M_PI;
            $field[] = "(2 * 6378.137 * ASIN(SQRT(POW(SIN($PI*({$param['latitude']}-latitude)/360),2)+COS($PI*{$param['latitude']}/180)* COS(latitude * $PI/180)*POW(SIN($PI*({$param['longitude']}-longitude)/360),2)))) as distance";
        }
        $info = self::where('id', $id)->field($field)->find();
        $param['store_id'] = $id;
        $info['house'] = House::tableList($param);
        return $info;
    }
    
    public static function getInfo($id)
    {
        $field = ['id', 'name', 'intro', 'images', 'address', 'phone', 'latitude', 'longitude', 'createtime','content'];
       
        $info = self::where('id', $id)->field($field)->find();
        return $info;
    }
}
